package com.hps.shiro.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hps.shiro.mapper.ClientMapper;
import com.hps.shiro.model.Client;
import com.hps.shiro.model.User;
import com.hps.shiro.service.AuthorizeService;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

/**
 * @author heps
 * @since 2020/6/8 11:41
 */
@AllArgsConstructor
@Service
public class AuthorizeServiceImpl implements AuthorizeService {

  private final ClientMapper clientMapper;

  private final StringRedisTemplate stringRedisTemplate;

  @Override
  public boolean checkClientId(String clientId) {
    Example example = new Example(Client.class);
    Criteria criteria = example.createCriteria();
    criteria.andEqualTo("clientId", clientId);
    List<Client> clients = clientMapper.selectByExample(example);
    if (CollectionUtils.isEmpty(clients)) {
      return false;
    }
    Client client = clients.get(0);
    ObjectMapper objectMapper = new ObjectMapper();
    try {
      String clientJson = objectMapper.writeValueAsString(client);
      stringRedisTemplate.opsForValue().set(clientId, clientJson);
      stringRedisTemplate.opsForValue().set(client.getClientSecret(), clientJson);
    } catch (JsonProcessingException e) {
      e.printStackTrace();
    }
    return true;
  }

  @Override
  public void addAuthCode(String authCode, User user) {
    stringRedisTemplate.opsForValue().set(authCode, JSON.toJSONString(user));
  }

  @Override
  public boolean checkClientSecret(String clientSecret) {
    return null != stringRedisTemplate.opsForValue().get(clientSecret);
  }

  @Override
  public boolean checkAuthCode(String authCode) {
    return null != stringRedisTemplate.opsForValue().get(authCode);
  }

  @Override
  public User getUsernameByAuthCode(String authCode) {
    String userJson = stringRedisTemplate.opsForValue().get(authCode);
    if (null == userJson) {
      return null;
    }
    return JSON.parseObject(userJson, User.class);
  }

  @Override
  public void addAccessToken(String accessToken, User user) {
    stringRedisTemplate.opsForValue().set(accessToken, JSON.toJSONString(user), 2, TimeUnit.HOURS);
  }

  @Override
  public long getExpireIn(String accessToken) {
    return stringRedisTemplate.getExpire(accessToken);
  }

  @Override
  public boolean checkAccessToken(String accessToken) {
    return null != stringRedisTemplate.opsForValue().get(accessToken);
  }

  @Override
  public User getUserByAccessToken(String accessToken) {
    String userJson = stringRedisTemplate.opsForValue().get(accessToken);
    if (null == userJson) {
      return null;
    }
    return JSON.parseObject(userJson, User.class);
  }
}
